/**
 * @file wa_label.c
 *
 */

/*********************
*      INCLUDES
*********************/
#include "wa_conf.h"
#if USE_WA_LABEL != 0
#include "wa_label.h"

/*********************
*      DEFINES
*********************/

/**********************
*      TYPEDEFS
**********************/

/**********************
*  STATIC PROTOTYPES
**********************/
static wa_obj_callback ancestor_callback;
static void wa_label_callback(wa_sign* sign);
/**********************
 *  STATIC VARIABLES
 **********************/


/**********************
*      MACROS
**********************/

/**********************
*   GLOBAL FUNCTIONS
**********************/
/**
* label module init
*/
void wa_label_module_init(void)
{
}

/**
* create a label
* @param par
* @return label obj
*/
wa_obj* wa_label_create(wa_obj* par)
{
	wa_obj* new_label;
	wa_label_ext* label_ext;
	
	new_label = wa_obj_create(par, NULL);
	if (new_label == NULL)
	{
		return new_label;
	}

	if (ancestor_callback == NULL)
	{
		ancestor_callback = wa_obj_get_callback(new_label);
	}
	label_ext = wa_obj_malloc_ext_attr(new_label, sizeof(wa_label_ext));
	if (label_ext == NULL)
	{
		return NULL;
	}

	label_ext->text = NULL;
	label_ext->row_space = 0;
	label_ext->col_space = 0;
	label_ext->font = NULL;
	label_ext->text_color = WA_COLOR_FOREGROUND;
	label_ext->back_color = WA_COLOR_BACKGROUND;
	label_ext->align_mode = WA_LABEL_AL_LEFT | WA_LABEL_AL_TOP;

	wa_obj_set_callback(new_label, wa_label_callback);

	return new_label;
}

/**
* label set text
* @param label
* @param text
*/
void wa_label_set_text(wa_obj* label, char* text)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	if (ext->text != NULL)
	{
		wa_free(ext->text);
	}
	if (text != NULL)
	{
		ext->text = wa_malloc(strlen((const char*)text) + 1);
		strcpy((char*)(ext->text), (char*)text);
	}
	else
	{
		ext->text = NULL;
	}
	wa_obj_invalidate(label);
}

/**
* label set row space
* @param label
* @param row space
*/
void wa_label_set_row_space(wa_obj* label, uint8_t row_space)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	ext->row_space = row_space;
	wa_obj_invalidate(label);
}

/**
* label set col space
* @param label
* @param col space
*/
void wa_label_set_col_space(wa_obj* label, uint8_t col_space)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	ext->col_space = col_space;
	wa_obj_invalidate(label);
}

/**
* label set font
* @param label
* @param font
*/
void wa_label_set_font(wa_obj* label, wa_font* font)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	ext->font = font;
	wa_obj_invalidate(label);
}

/**
* label set text color
* @param label
* @param text color
*/
void wa_label_set_text_color(wa_obj* label, wa_gui_color color)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	ext->text_color = color;
	wa_obj_invalidate(label);
}

/**
* label set back color
* @param label
* @param back color
*/
void wa_label_set_back_color(wa_obj* label, wa_gui_color color)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	ext->back_color = color;
	wa_obj_invalidate(label);
}

/**
* label set align mode
* @param label
* @param align mode
*/
void wa_label_set_align_mode(wa_obj* label, uint8_t align_mode)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	ext->align_mode = align_mode;
	wa_obj_invalidate(label);
}

/**
* label get text
* @param label
* @param text dst array point
* @param size how many want to get
* @return how many get
*/
int32_t wa_label_get_text(wa_obj* label, char* text, uint32_t size)
{
	wa_label_ext* ext;
	uint32_t len;
	ext = wa_obj_get_ext_attr(label);
	if (ext->text == NULL)
	{
		return -1;
	}
	len = strlen((const char*)(ext->text)) + 1;
	if (size >= len)
	{
		strcpy((char*)text, (char*)(ext->text));
		return len;
	}
	else
	{
		memcpy(text, ext->text, size);
		return size;
	}
}

/**
* label get row space
* @param label
* @return row space
*/
uint8_t wa_label_get_row_space(wa_obj* label)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	return ext->row_space;
}

/**
* label get col space
* @param label
* @return col space
*/
uint8_t wa_label_get_col_space(wa_obj* label)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	return ext->col_space;
}

/**
* label get font
* @param label
* @return font
*/
wa_font* wa_label_get_font(wa_obj* label)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	return ext->font;
}

/**
* label get text color
* @param label
* @return text color
*/
wa_gui_color wa_label_get_text_color(wa_obj* label)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	return ext->text_color;
}

/**
* label get back color
* @param label
* @return back color
*/
wa_gui_color wa_label_get_back_color(wa_obj* label)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	return ext->back_color;
}

/**
* label get align mode
* @param label
* @return align mode
*/
uint8_t wa_label_get_align_mode(wa_obj* label)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(label);
	return ext->align_mode;
}

/**********************
*   STATIC FUNCTIONS
**********************/

/**
* label redraw functions 
* @param obj
*/
static void _Paint(wa_obj* obj)
{
	wa_label_ext* ext;
	int str_w, str_h;
	int str_x = 0;
	int str_y = 0;
	wa_area str_area;
	ext = wa_obj_get_ext_attr(obj);

	wa_mask_fillrect(obj->rect.x1, obj->rect.y1,
					wa_obj_get_width(obj),
					wa_obj_get_height(obj),
					&(obj->redraw_rect),
					ext->back_color);

	if (ext->font == NULL)
	{
		return;
	}
	if (ext->text == NULL)
	{
		return;
	}

	wa_font_get_str_size(&str_w, &str_h, (uint8_t*)ext->text, ext->font, ext->row_space, ext->col_space);
	if ((ext->align_mode & 0x03) == WA_LABEL_AL_LEFT)
	{
		str_x = obj->rect.x1;
	}
	else if ((ext->align_mode & 0x03) == WA_LABEL_AL_RIGHT)
	{
		str_x = obj->rect.x2 - str_w;
	}
	else if ((ext->align_mode & 0x03) == WA_LABEL_AL_HCENTER)
	{
		str_x = obj->rect.x1 + ((int)(wa_obj_get_width(obj)) - (int)str_w) / 2;
	}
	else
	{

	}

	if ((ext->align_mode & 0x0c) == WA_LABEL_AL_TOP)
	{
		str_y = obj->rect.y1;
	}
	else if ((ext->align_mode & 0x0c) == WA_LABEL_AL_BOTTOM)
	{
		str_y = obj->rect.y2 - str_h;
	}
	else if ((ext->align_mode & 0x0c) == WA_LABEL_AL_VCENTER)
	{
		str_y = obj->rect.y1 + ((int)(wa_obj_get_height(obj)) - (int)str_h) / 2;
	}
	else
	{

	}
	str_area.x1 = str_x;
	str_area.y1 = str_y;
	str_area.x2 = str_x + str_w - 1;
	str_area.y2 = str_y + str_h - 1;

	wa_mask_dispstr_1(&str_area, (uint8_t*)ext->text, ext->font,
					ext->row_space, ext->col_space,
					&(obj->redraw_rect),
					ext->text_color);
}

/**
 * label obj delete function
 * @param obj
 */
static void _Delete(wa_obj* obj)
{
	wa_label_ext* ext;
	ext = wa_obj_get_ext_attr(obj);
	if (ext->text != NULL)
	{
		wa_free(ext->text);
	}
}

/**
 * label obj callback function
 * @param sign
 */
static void wa_label_callback(wa_sign* sign)
{
	int sign_id;
	wa_obj* obj;

	ancestor_callback(sign);
	sign_id = sign->sign_id;
	obj = sign->obj_dst;

	switch (sign_id)
	{
		case WA_SIGNAL_PAINT:
		{
			_Paint(obj);
			break;
		}
		case WA_SIGNAL_DELETE:
		{
			_Delete(obj);
			break;
		}
		default:
		{
			break;
		}
	}
}

#endif
